package com.chnbst.bstyun.eos;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ConfigUtil
{
  private static Log log = LogFactory.getLog(ConfigUtil.class);

  private static Map<String, Properties> cachedProperties = new HashMap();
  public static final String JAR_FILE_PATH_PREFIX = "file:/";
  public static final String JAR_FILE_PATH_ENDFIX = "!";
  public static final String JAR_FILE_EXTENSION = ".jar";
  public static final String JAR_PREFIX_KEY = "jar.prefix";

  public static String getJarFilePath(String path)
  {
    if (path.indexOf("!") != -1) {
      path = path.substring(0, path.indexOf("!"));
    }
    if (path.indexOf("file:/") != -1) {
      path = path.substring(path.indexOf("file:/") + 
        "file:/".length());
    }
    if ((System.getProperty("os.name").toUpperCase().indexOf("WINDOWS") == -1) && 
      (!path.startsWith("/"))) {
      path = "/" + path;
    }

    return path;
  }

  public static Properties getPropertiesForClassPathOrJarFile(String jarPrefix, String configFileName)
  {
    return getPropertiesForClassPathOrJarFile(false, jarPrefix, 
      configFileName);
  }

  public static Properties getPropertiesForClassPathOrJarFile(boolean reload, String jarPrefix, String configFileName)
  {
    if ((reload) && 
      (cachedProperties.containsKey(configFileName))) {
      cachedProperties.remove(configFileName);
    }

    String[] prefixes = null;
    if (jarPrefix.indexOf(",") != -1)
      prefixes = jarPrefix.split(",");
    else
      prefixes = new String[] { jarPrefix };
    for (String prefix : prefixes) {
      if ((!cachedProperties.containsKey(configFileName)) || 
        (((Properties)cachedProperties.get(configFileName)).getProperty(
        "jar.prefix") == null) || 
        (((Properties)cachedProperties.get(configFileName)).getProperty(
        "jar.prefix").indexOf(prefix) == -1)) {
        Properties p = getPropertiesForClassPathOrJarFile(prefix, 
          configFileName, configFileName);
        if ((p != null) && (p.size() > 0)) {
          p.put("jar.prefix", jarPrefix);
          cachedProperties.put(configFileName, p);
          return p;
        }
      }
      else
      {
        return (Properties)cachedProperties.get(configFileName);
      }
    }
    return new Properties();
  }

  public static Properties getPropertiesForClassPathOrJarFile(String configFileName)
  {
    return getPropertiesForClassPathOrJarFile("focu-", configFileName);
  }

  public static String getJarPathIfExists() {
    URL url = ConfigUtil.class.getProtectionDomain().getCodeSource()
      .getLocation();
    if (url != null) {
      String path = url.getPath();
      if (path.indexOf(".jar") != -1)
        return getJarFilePath(url.getPath());
    }
    return null;
  }

  public static Properties getPropertiesForClassPathOrJarFile(String jarPrefix, String classPathFileName, String inJarFileName)
  {
    if ((StringUtils.isBlank(classPathFileName)) || 
      (StringUtils.isBlank(inJarFileName))) {
      return null;
    }
    Properties config = null;
    InputStream in = null;
    String configFilePath = null;
    try
    {
      log.info("Looking for " + classPathFileName + 
        " config file in classpath.");

      URL configUrl = null;
      try {
        configUrl = ConfigUtil.class.getClassLoader().getResource(".");
        if ((configUrl != null) && 
          (!configUrl.getPath().endsWith("classes/")) && 
          (!configUrl.getPath().endsWith("bin/")))
          configUrl = ConfigUtil.class.getClassLoader()
            .getResource("/");
      }
      catch (Throwable e)
      {
        try {
          configUrl = ConfigUtil.class.getClassLoader().getResource(
            "/");
        }
        catch (Exception localException)
        {
        }
      }
      config = new Properties();

      if (configUrl != null)
      {
        configFilePath = configUrl.getPath() + classPathFileName;

        File sysConfigFile = new File(configFilePath);

        if ((sysConfigFile != null) && (sysConfigFile.exists()) && 
          (sysConfigFile.isFile())) {
          try {
            in = new FileInputStream(sysConfigFile);

            config.load(in);

            log.info("Using configuration file " + configFilePath + 
              " in the classpath.");
          }
          finally
          {
            if (in != null)
              try {
                in.close();
              }
              catch (IOException localIOException) {
              }
            else log.error("Could not find " + inJarFileName + 
                " in the classpath!");
          }
        }
        else
        {
          log.warn("Could not find " + classPathFileName + 
            " in classpath.\nSystem will use " + 
            inJarFileName + " config file in jar.");

          if (!inJarFileName.equals(classPathFileName)) {
            configUrl = ConfigUtil.class.getClassLoader()
              .getResource(inJarFileName);
            if (configUrl != null) {
              configFilePath = configUrl.getPath();
            }
          }

          File libPath = new File(new File(configUrl.getPath())
            .getParent() + 
            File.separatorChar + "lib");
          File[] jars = libPath.listFiles();

          if (jars == null) {
            return null;
          }
          if (inJarFileName.startsWith("/")) {
            inJarFileName = inJarFileName.substring(1);
          }
          for (File jar : jars) {
            if (jar.getName().startsWith(jarPrefix)) {
              String inJarPath = jar.getAbsolutePath().replace(
                '\\', '/');
              JarFile jarFile = new JarFile(inJarPath);
              if (jarFile != null) {
                ZipEntry entry = jarFile
                  .getEntry(inJarFileName);
                if (entry != null) {
                  try {
                    in = jarFile.getInputStream(entry);
                    Properties p = new Properties();
                    p.load(in);
                    config.putAll(p);
                    log
                      .info("Loading properties file from URL[jar:file:/" + 
                      inJarPath + 
                      "!" + 
                      inJarFileName + "]");
                  } finally {
                    if (in != null)
                      try {
                        in.close();
                      }
                      catch (IOException localIOException2) {
                      }
                    else log
                        .error("Could not find " + 
                        inJarFileName + 
                        " in the classpath!\nThis may be due to a wrong-packaged or corrupted jar file.");

                  }

                }

              }

            }

          }

        }

      }

      return config;
    } catch (IOException localIOException4) {
    }
    return null;
  }

  public static void interatorDirectoryForClassPathOrJarFile(String jarPrefix, List<String> newLocations, String location, String[] extensions)
  {
    if (!location.endsWith("/")) {
      location = location + "/";
    }
    URL url = ConfigUtil.class.getClassLoader().getResource(location);
    if (url != null) {
      if (((extensions == null) || (extensions.length == 0)) && 
        (!newLocations.contains(location))) {
        newLocations.add(location);
      }
      String path = url.getPath();
      File f = new File(path);
      File[] subFiles = f.listFiles();
      if (subFiles != null)
      {/*
        File[] arrayOfFile2;
        int i = (arrayOfFile2 = subFiles).length; for (localFile1 = 0; localFile1 < i; localFile1++) { sfile = arrayOfFile2[localFile1];
          if (sfile.isDirectory())
          {
            String nlocation = location + sfile.getName() + "/";
            interatorDirectoryForClassPathOrJarFile(jarPrefix, 
              newLocations, nlocation, extensions);
          }

          if ((sfile.isFile()) && 
            (extensions != null) && (extensions.length > 0)) {
            for (String extension : extensions) {
              if (sfile.getName().endsWith(extension)) {
                String nlocation = location + 
                  sfile.getName();
                if (!newLocations.contains(nlocation)) {
                  newLocations.add(nlocation);
                }
              }
            }
          }
        }
      */}
    }

    File libPath = new File(new File(ConfigUtil.class.getClassLoader()
      .getResource("/").getPath()).getParent() + 
      File.separatorChar + "lib");
    File[] jars = libPath.listFiles();

    if (location.startsWith("/"))
      location = location.substring(1);
    File[] arrayOfFile1;
//    File localFile1 = (arrayOfFile1 = jars).length; for (File sfile = 0; sfile < localFile1; sfile++) { File jar = arrayOfFile1[sfile];
//      if (jar.getName().startsWith(jarPrefix)) {
//        String inJarPath = jar.getAbsolutePath().replace('\\', '/');
//        JarFile jarFile = null;
//        try {
//          jarFile = new JarFile(inJarPath);
//        } catch (IOException e) {
//          e.printStackTrace();
//        }
//
//        Enumeration enums = jarFile.entries();
//        while (enums.hasMoreElements()) {
//          JarEntry jarEntry = (JarEntry)enums.nextElement();
//          String name = jarEntry.getName();
//          if ((extensions == null) || (extensions.length == 0)) {
//            if ((name.startsWith(location)) && (jarEntry.isDirectory()) && 
//              (!newLocations.contains(name)))
//              newLocations.add(name);
//          }
//          else
//            for (String extension : extensions)
//              if ((name.startsWith(location)) && 
//                (name.endsWith(extension)) && 
//                (!newLocations.contains(name)))
//                newLocations.add(name);
//        }
//      }
//    }
  }

  public static List<String> getFilesByExtensionsFromClassPathAndJarFile(String jarPrefix, String[] extensions, String[] locations)
  {
    List newLocations = new ArrayList();
    for (String location : locations) {
      interatorDirectoryForClassPathOrJarFile(jarPrefix, newLocations, 
        location, extensions);
    }
    return newLocations;
  }

  public static List<String> getFilesForClassPathOrJarFile(String[] extensions, String[] locations)
  {
    List mappings = new ArrayList();

    String path = null;

    for (String plLocation : locations)
    {
      path = ConfigUtil.class.getClassLoader().getResource(plLocation)
        .getPath();

      File file = new File(path);

      File[] files = file.listFiles();
      String str1;
      String extension;
      if (files != null) {
        for (File f : files) {
          if (f.isFile()) {
            if (extensions == null) {
              mappings.add(plLocation + f.getName());
            }
            else {/*
              String[] arrayOfString3 = extensions; int n = extensions.length; for (str1 = 0; str1 < n; str1++) { extension = arrayOfString3[str1];
                if (f.getName().endsWith(extension)) {
                  mappings.add(plLocation + f.getName());
                }
              }
            */}
          }
        }
      }
      if (path.indexOf(".jar") != -1)
        path = getJarFilePath(path);
      else {
        path = getJarPathIfExists();
      }
      if (!StringUtils.isBlank(path))
      {
        JarFile jarFile = null;
        try
        {
          jarFile = new JarFile(new File(path));
        }
        catch (IOException e)
        {
          e.printStackTrace();
        }

        if (jarFile != null)
        {
          Enumeration enums = jarFile.entries();

          while (enums.hasMoreElements())
          {
            JarEntry entry = (JarEntry)enums.nextElement();

            if ((!entry.isDirectory()) && 
              (entry.getName().startsWith(plLocation)))
            {
              if ((extensions == null) && 
                (!mappings.contains(entry.getName()))) {
                mappings.add(entry.getName());
              }
              else
              {/*
                String[] arrayOfString2 = extensions; str1 = extensions.length; for (extension = 0; extension < str1; extension++) { String extension = arrayOfString2[extension];

                  if ((entry.getName().endsWith(extension)) && 
                    (!mappings.contains(entry.getName())))
                  {
                    mappings.add(entry.getName());
                  }
                }
              */}
            }
          }
        }

      }

    }

    return mappings;
  }

  public static void refresh() {
    cachedProperties.clear();
  }
}